<template>
  <!-- 自学模式 -->
  <div class="sbodyd">
    <!-- 图谱详情主体区域-->
    <div class="mainboxgj">
      <!-- 修改为不分 -->
      <div class="mainboxleft" v-if="lodings">
        <!-- 分上方区域 -->
        <!-- 顶部标题栏目 -->
        <div class="maintopbox">
          <div class="mainsera">
            <div class="gobackbox">
              <div class="xbannername" @click="goback">关闭</div>
            </div>
          </div>

          <div class="maintoptitle"></div>
          <div class="maintopright">
            <div class="czmainitem tool" @click="zoomIn">
              <img src="@/images/fd.png" alt="" class="normal" />
              <img src="@/images/fdac.png" alt="" class="active" />
            </div>
            <div class="czmainitem tool" @click="zoomOut">
              <img src="@/images/sx.png" alt="" class="normal" />
              <img src="@/images/sxac.png" alt="" class="active" />
            </div>
            <div class="czmainitem tool" @click="tdflag = true">
              <img src="@/images/td.png" alt="" class="normal" />
              <img src="@/images/tdac.png" alt="" class="active" />
            </div>
            <div class="czmainitem tool" @click="reset">
              <img src="@/images/cz.png" alt="" class="normal" />
              <img src="@/images/czac.png" alt="" class="active" />
            </div>
          </div>
        </div>
        <!-- 分下方区域 -->
        <div class="mainbottombox">
          <!-- 分左侧区域 -->
          <div class="mainbottomboxleft">
            <!-- 画布区域 -->
            <div
              class="box"
              ref="box"
              id="canvasContainer"
              :style="{
                backgroundColor: atlasTypeName == '插画' ? '#ffff' : 'black',
              }"
            >
              <canvas
                id="myCanvas"
                :width="hbwidth / 2"
                :height="hbheight"
                :style="{
                  cursor: myStyle,
                  backgroundColor: atlasTypeName == '插画' ? '#ffff' : 'black',
                }"
              >
              </canvas>
              <canvas
                id="myCanvas2"
                :width="hbwidth / 2"
                :height="hbheight"
                :style="{
                  cursor: myStyle,
                  marginLeft: hbwidth / 2,
                }"
              >
              </canvas>

              <!--           @mousedown="currentMode == 'drawing' ? startDrawing : null"
                @mouseup="currentMode == 'drawing' ? stopDrawing : null"
                @mousemove="currentMode == 'drawing' ? draws : null" -->
              <canvas
                v-show="isCanvasVisible"
                id="overlayCanvas"
                :width="hbwidth"
                :height="hbheight"
                ref="overlayCanvas"
                @touchstart="startDrawing"
                @touchend="stopDrawing"
                @touchmove="draws"
                @mousedown="startDrawing"
                @mouseup="stopDrawing"
                @mousemove="draws"
                @click="showTextInput"
                :style="{ cursor: currentCursorStyle }"
              >
              </canvas>
              <div class="overlayCanvastool" v-show="isCanvasVisible">
                <div
                  class="overlayCanvastooitem"
                  :class="
                    currentMode == 'text' ? 'overlayCanvastooitems' : null
                  "
                  @click="enableTextMode"
                >
                  T
                </div>

                <div class="overlayCanvastooitem" @click="clearOverlay">
                  删除
                </div>
                <div>
                  <input
                    id="size"
                    type="range"
                    min="1"
                    max="10"
                    v-model="brushSize"
                  />
                </div>
              </div>
              <div
                v-if="showInput"
                :style="inputStyle"
                class="text-input-container"
              >
                <input
                  v-model="customText"
                  @keydown.enter="addTextMarkerOnEnter"
                  class="text-input"
                  placeholder="输入要添加的文字"
                  @focus="isInputActive = true"
                  @blur="handleInputBlur"
                />
              </div>
            </div>
            <!-- 底部图片轮播 -->
            <div class="lboxmain">
              <!-- 页码 -->
              <div class="gnbottom" v-if="!loding">
                <div class="mentox">影像页数:</div>
                <div class="mentoxs">
                  <div class="tool" @click="tagdcoms('-1')">
                    <img src="@/images/letac.png" alt="" class="normal" />
                    <img src="@/images/let.png" alt="" class="active" />
                  </div>
                  <span>{{ findindex() + 1 }}/{{ imgsrc.length }}</span>
                  <div class="tool" @click="tagdcoms('1')">
                    <img src="@/images/rght.png" alt="" class="normal" />
                    <img src="@/images/rghtac.png" alt="" class="active" />
                  </div>
                </div>
              </div>
              <!-- 影像图 -->
              <div class="lbox" ref="gosroll" @scroll="getScrollPosition">
                <div
                  v-for="(item, index) in imgsrc"
                  :key="item.medicineAtlasImgId"
                  class="lboxitem"
                  @click="tagdcom(item.medicineAtlasImgId, '')"
                >
                  <img :src="`${base + item.imgUrl}`" />
                  <div
                    class="msx"
                    v-if="item.medicineAtlasImgId == dcomid"
                  ></div>
                </div>
              </div>
            </div>
          </div>

          <!-- 分右侧区域 -->
          <!-- 菜单 -->
          <div class="bocd beautifulScroll">
            <div class="mentname">
              <div class="menttitle">
                <img src="@/images/cdicon.png" alt="" />
                菜单
              </div>
            </div>
            <div class="mentbjbox">
              <div class="mentbjtitle">标记</div>
              <div class="mentbjtiem">
                <div class="jgdovx mentbjtiems">
                  添加批注
                  <el-switch v-model="pzshow" @change="pzfn()" />
                </div>
              </div>
              <div class="mentbjtiem">
                <div class="jgdovx mentbjtiems">
                  局部标签
                  <el-switch v-model="jubushow" @change="jubu()" />
                </div>
              </div>
              <div class="mentbjacitem" v-show="isCanvasVisible">
                <!-- 撤销 -->
                <div
                  class="tool mentbjacitemtool"
                  :class="{ active: selectedTool === 'undo' }"
                  @click="undo"
                >
                  <img src="@/images/m1.png" alt="" class="normal" />
                  <img src="@/images/m1ac.png" alt="" class="active" />
                </div>
                <!-- 还原 -->
                <div
                  class="tool mentbjacitemtool"
                  :class="{ active: selectedTool === 'redo' }"
                  @click="redo"
                >
                  <img src="@/images/m2.png" alt="" class="normal" />
                  <img src="@/images/m2ac.png" alt="" class="active" />
                </div>
                <!-- 绘制 -->
                <div
                  class="tool mentbjacitemtool"
                  :class="{ active: selectedTool === 'drawing' }"
                  @click="enableDrawingMode"
                >
                  <img src="@/images/m3.png" alt="" class="normal" />
                  <img src="@/images/m3ac.png" alt="" class="active" />
                </div>

                <!-- 橡皮擦 -->
                <div
                  class="tool mentbjacitemtool"
                  :class="{ active: selectedTool === 'eraser' }"
                  @click="toggleEraser"
                >
                  <img src="@/images/m4.png" alt="" class="normal" />
                  <img src="@/images/m4ac.png" alt="" class="active" />
                </div>
                <!-- 选择颜色 -->
                <div class="tool mentbjacitemtool" style="position: relative">
                  <input
                    id="color"
                    type="color"
                    v-model="brushColor"
                    class="colorts"
                  />
                  <img src="@/images/m5.png" alt="" class="normal" />
                  <img src="@/images/m5ac.png" alt="" class="active" />
                </div>
                <!-- 选择粗细 -->
                <div
                  class="tool mentbjacitemtool"
                  style="position: relative"
                  @click="hbcshow = !hbcshow"
                >
                  <div class="hbcbox" v-if="hbcshow">
                    <div
                      class="hbcitem"
                      @click="(brushSize = item), (hbcshow = false)"
                      v-for="(item, index) in brushSizedata"
                      :style="{
                        border: item + 'px solid #ffffff',
                      }"
                      :key="index"
                    ></div>
                  </div>
                  <img src="@/images/m6.png" alt="" class="normal" />
                  <img src="@/images/m6ac.png" alt="" class="active" />
                </div>
                <div
                  class="tool mentbjacitemtool"
                  :class="{ active: selectedTool === 'clear' }"
                  @click="clearOverlay"
                >
                  <img src="@/images/m7.png" alt="" class="normal" />
                  <img src="@/images/m7ac.png" alt="" class="active" />
                </div>
              </div>
            </div>

            <div class="mentbjbox">
              <div class="mentbjtitle">筛选</div>
              <div class="mentsxbox">
                <div class="mentsxtitle">扫描方向</div>
                <div class="mentsxtitembox">
                  <div
                    :class="
                      classificationName == '全部'
                        ? 'mentsxitems'
                        : 'mentsxitem'
                    "
                    @click="changeimgclassfn('全部')"
                  >
                    全部
                  </div>
                  <div
                    :class="
                      classificationName == item.classificationName
                        ? 'mentsxitems'
                        : 'mentsxitem'
                    "
                    v-for="item in imgclassdata"
                    :key="item.classificationName"
                    @click="changeimgclassfn(item.classificationName)"
                  >
                    {{ item.classificationName }}
                  </div>
                </div>
              </div>
              <div class="mentsxbox" v-show="imggroup.length > 0">
                <div class="mentsxtitle">加权</div>
                <div class="mentsxtitembox">
                  <div
                    :class="
                      imggroupname == '全部' ? 'mentsxitems' : 'mentsxitem'
                    "
                    @click="changeimggroupfn('全部', true)"
                  >
                    全部
                  </div>
                  <div
                    v-for="(item, index) in imggroup"
                    :key="index"
                    :class="
                      imggroupname == item.typeName
                        ? 'mentsxitems'
                        : 'mentsxitem'
                    "
                    @click="changeimggroupfn(item.typeName, true)"
                  >
                    {{ item.typeName }}
                  </div>
                </div>
              </div>
            </div>

            <div class="mentbjbox">
              <div class="mentbjtitle">解剖部位</div>

              <div class="mentbjtiem" v-if="optionsdata.length > 0">
                <div class="jgdovx mentbjtiems">
                  全部
                  <el-switch v-model="allflag" @change="changecsd()" />
                </div>
              </div>
              <div
                class="mentbjtiem"
                v-for="(item, index) in anatomicStructure"
                :key="index"
                v-show="flagfn(item)"
              >
                <div class="jgdovx mentbjtiems">
                  {{ item.anatomicStructureName }}
                  <el-switch v-model="item.flag" @change="changecs(item)" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 知识点补充div -->
    <div class="zsbox" v-if="visible">
      <div class="mentname">
        <div class="menttitle">
          <img src="@/images/cdicon.png" alt="" />
          知识点补充
        </div>
        <div class="mentright" @click="visible = false">
          <img src="@/images/close-circle-filled.png" alt="" class="clseo" />
        </div>
      </div>

      <div class="zsbot">
        <div class="zsdkz">
          {{ bwstuddata.system }}> {{ bwstuddata.partsName }}>
          {{ bwstuddata.anatomicStructureName }}> {{ bwstuddata.pointName }}({{
            bwstuddata.pointNameEng
          }})

          <div v-if="bwstuddata.pointContent != ''">
            <v-md-preview
              :text="bwstuddata.pointContent"
              class="zsdkz"
            ></v-md-preview>
            <!-- <div class="zsdkz" v-html="bwstuddata.pointContent"> </div
              >-->
          </div>
          <div v-else>
            <div class="zsdkz">暂无知识点补充!</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 加载页 -->
    <div class="loader-container" v-if="loding">
      <div class="loader"></div>
      <p class="pd">加载中98%</p>
    </div>
  </div>
</template>

<script>
  // import {
  //
  //   getxqPoint 查询点位详情可以删除这里用不到了,
  //   getPointjs 查询富文本不用了,

  //
  // } from '@/api/atlas'
  import { debounce } from 'lodash';
  import { newdata } from '@/mixin/data';
  export default {
    //混入
    mixins: [newdata],
    data() {
      return {
        loding: false,
        lodings: false,
        medicineAtlasId: 23,
        atlasTypeName: '空客删除',
        box: null,
        markingPointsIdxz: '',
        optionsselect: [],
        visible: false,
        base: 'http://192.168.1.100',
        canvasHistory: [], // 添加画布历史记录数组
        redoHistory: [], // 添加重做历史记录数组
        state: {
          labels: null,
          showText: true,
          canBiaoZhu: false,
          pointColor: '#65FF00',
          pointSize: 7,
          imgScale: 1,
          zoomStep: 0.1,
          markers: [],
          canvas: null,
          ctx: null,
          img: new Image(),
          imgWidth: 480,
          imgHeight: 606,
          imgPosition: { x: 0, y: 0 },
          currentText: '',
          currentMarker: {},
          showLinesAndText: true,
          isDragging: false,
          startDragX: 0,
          startDragY: 0,
          imgOffsetX: 0,
          imgOffsetY: 0,
          isSpacePressed: false,
          hoveredMarker: null,
          editingMarker: false,
          editPanelX: 0,
          editPanelY: 0,
          addflag: false,
          flipHorizontal: false,
          flipVertical: false,
          rotation: 0,
          canvas2: null,
        },
        markingPointsId: '',
        dcomid: Number(localStorage.getItem('dcomid')) || 1,

        visiblest: false,
        formModel: {
          userText: '',
        },
        bwstuddata: null,
        optionsdata: [
          { anatomicStructureName: '', flag: true, anatomicStructureId: '' },
        ],
        gosroll: null,
        jiegoudata: [],
        oneshow: false,
        startX: 0,
        startY: 0,
        isSwiping: false,
        startTime: 0,
        threshold: 30,
        fastSwipeThreshold: 200,
        fastSwipeDistance: 50,
        slowSwipeThreshold: 10,
        slowSwipeTimeThreshold: 200,
        isFastSwipe: false,
        hasMoved: false,
        tdflag: false,
        flag: false,
        hbheight: null,
        hbwidth: null,
        leftMarkers: [],
        rightMarkers: [],
        textModeEnabled: false,
        jubushow: false,
        pzshow: false,
        myStyle: 'inherit',
        context: null,
        overlayContext: null,
        isDrawing: false,
        isCanvasVisible: false,
        customText: '',
        showInput: false,
        inputStyle: {
          left: '',
          top: '',
          position: 'absolute',
        },
        isInputActive: false,
        currentMode: null,
        currentCursorStyle: 'inherit',
        brushColor: '#ff0000',
        brushSize: 2,
        isEraserMode: false,
        hbcshow: false,
        brushSizedata: [1, 2, 2.5, 3, 3.5, 4],
        allflag: true,
        classificationName: '全部',
        imggroupname: '全部',
        anatomicStructure: [
          {
            anatomicStructureName: '',
            flag: false,
            anatomicStructureId: '',
          },
        ],
        selectedTool: null, // 添加选中状态跟踪
      };
    },
    computed: {
      userdata() {
        return this.$store.state.user;
      },
    },
    created() {
      this.gettpxq();
    },
    mounted() {
      this.handleResize = debounce(this.handleResize, 200);
      window.addEventListener('resize', this.handleResize);

      // 添加键盘事件监听
      document.addEventListener('keydown', this.handleKeyDown);
      document.addEventListener('keyup', this.handleKeyUp);
    },
    beforeDestroy() {
      const canvas = document.getElementById('myCanvas');
      if (canvas) {
        canvas.removeEventListener('wheel', this.handleWheel);
      }
      const canvas2 = document.getElementById('myCanvas2');
      if (canvas2) {
        canvas.removeEventListener('wheel', this.handleWheel);
      }
      window.removeEventListener('resize', this.handleResize);
      document.removeEventListener('keydown', this.handleKeyDown);
      document.removeEventListener('keyup', this.handleKeyUp);
    },
    methods: {
      gettpxq() {
        this.loding = true;
        //   tpxqList({ medicineAtlasId: this.medicineAtlasId }).then((res) => {
        //     if (res.code == 200) {
        //     }
        //   })

        //   this.imgsrc = res.data.allImg 所有图谱列表
        //   this.imgsrcs = res.data.allImg 所有图谱列表
        //   this.imggroup = res.data.group 图谱组用不到后面可以删除
        //   this.imgclassdata = res.data.classification
        this.lodings = true;
        // 确保 box 元素已经挂载
        this.$nextTick(() => {
          if (!this.$refs.box) {
            console.warn('Box element not found');
            this.loding = false;
            return;
          }

          this.hbheight = this.$refs.box.offsetHeight;
          this.hbwidth = this.$refs.box.offsetWidth;

          // 初始化画布
          this.state.canvas = document.getElementById('myCanvas');

          if (!this.state.canvas) {
            console.warn('Canvas element not found');
            this.loding = false;
            return;
          }

          this.state.ctx = this.state.canvas.getContext('2d', {
            willReadFrequently: true,
          });
          this.state.img = new Image();
          this.state.img.crossOrigin = 'anonymous';

          const imgsrcd = this.imgsrc.find(
            (item) => item.medicineAtlasImgId == this.dcomid
          );

          if (!imgsrcd) {
            this.state.img.src = this.base + this.imgsrc[0].imgUrl;
            this.dcomid = this.imgsrc[0].medicineAtlasImgId;
          } else {
            this.state.img.src = this.base + imgsrcd.imgUrl;
          }

          this.state.img.onload = () => {
            this.state.imgWidth = this.state.img.naturalWidth;
            this.state.imgHeight = this.state.img.naturalHeight;
            this.loadMarkers();

            // 在数据加载完成后添加事件监听
            if (this.state.canvas) {
              this.state.canvas.addEventListener('wheel', this.handleWheel, {
                passive: false,
              });
              this.state.canvas.addEventListener('mousedown', this.startDrag);
              this.state.canvas.addEventListener(
                'mousemove',
                this.handleMouseMove
              );
              this.state.canvas.addEventListener('mouseup', this.stopDrag);
              this.state.canvas.addEventListener('mouseleave', this.stopDrag);
              this.state.canvas.addEventListener(
                'click',
                this.handleCanvasClick
              );
              this.state.canvas.addEventListener(
                'touchstart',
                this.handleTouchStart,
                { passive: false }
              );
              this.state.canvas.addEventListener(
                'touchmove',
                this.handleTouchMove,
                { passive: false }
              );
              this.state.canvas.addEventListener(
                'touchend',
                this.handleTouchEnd,
                { passive: false }
              );
            }

            //   处理解刨点位数据
            this.state.markers = [];
            this.saveMarkers();
            const markersMap = new Map(
              this.state.markers.map((marker) => [
                marker.medicineAtlasImgId,
                marker,
              ])
            );
            for (const items of this.Pointnewdata) {
              try {
                if (items.medicineAtlasImgId != null) {
                  const existingMarker = markersMap.get(
                    items.medicineAtlasImgId
                  );
                  const markingPointsObjects = JSON.parse(items.markingPoints);
                  markingPointsObjects.medicineAtlasImgId =
                    items.medicineAtlasImgId;
                  markingPointsObjects.bsdata[0].markingPointsId =
                    items.markingPointsId;
                  markingPointsObjects.bsdata[0].flag = true;
                  markingPointsObjects.bsdata[0].labels = true;
                  markingPointsObjects.bsdata[0].anatomicStructureName =
                    items.anatomicStructureName;
                  markingPointsObjects.bsdata[0].anatomicStructureId =
                    items.anatomicStructureId;
                  if (existingMarker) {
                    existingMarker.bsdata.push(...markingPointsObjects.bsdata);
                  } else {
                    markersMap.set(
                      items.medicineAtlasImgId,
                      markingPointsObjects
                    );
                  }
                }
              } catch (error) {
                console.error('Error processing item:', items, error);
              }
              this.state.markers = Array.from(markersMap.values());
              // 处理解剖点数据完成

              // 获取解剖结构数据
              this.optionsdata = this.jgListdata.map((item) => {
                // 这一步后面可以删除这是增加开关判断
                return { ...item, flag: true };
              });

              this.anatomicStructurefn();
              // 处理解剖结构完成
              // 获取图像大小
              this.getimgsize();
              // 开始绘制
              this.draw('');
              this.loding = false;
            }
          };

          this.state.img.onerror = (error) => {
            console.error('Failed to load image:', error);
            this.loding = false;
          };
          // 初始化画布1完成

          //初始化画布2
          this.state.canvas2 = document.getElementById('myCanvas2');
          if (!this.state.canvas2) {
            console.warn('Canvas element not found');
            this.loding = false;
            return;
          }
          this.state.ctx2 = this.state.canvas2.getContext('2d', {
            willReadFrequently: true,
          });
          // this.state.ctx = this.state.canvas.getContext('2d', {
          //   willReadFrequently: true,
          // });
          // this.state.img = new Image();
          // this.state.img.crossOrigin = 'anonymous';

          // const imgsrcd2 = this.imgsrc.find(
          //   (item) => item.medicineAtlasImgId == this.dcomid
          // );

          // if (!imgsrcd2) {
          //   this.state.img.src = this.base + this.imgsrc[0].imgUrl;
          //   this.dcomid = this.imgsrc[0].medicineAtlasImgId;
          // } else {
          //   this.state.img.src = this.base + imgsrcd.imgUrl;
          // }

          // this.state.img.onload = () => {
          //   this.state.imgWidth = this.state.img.naturalWidth;
          //   this.state.imgHeight = this.state.img.naturalHeight;
          //   this.loadMarkers();

          //   // 在数据加载完成后添加事件监听
          //   // if (this.state.canvas2) {
          //   //   this.state.canvas2.addEventListener('wheel', this.handleWheel, {
          //   //     passive: false,
          //   //   });
          //   //   this.state.canvas2.addEventListener('mousedown', this.startDrag);
          //   //   this.state.canvas2.addEventListener(
          //   //     'mousemove',
          //   //     this.handleMouseMove
          //   //   );
          //   //   this.state.canvas2.addEventListener('mouseup', this.stopDrag);
          //   //   this.state.canvas2.addEventListener('mouseleave', this.stopDrag);
          //   //   this.state.canvas2.addEventListener(
          //   //     'click',
          //   //     this.handleCanvasClick
          //   //   );
          //   //   this.state.canvas2.addEventListener(
          //   //     'touchstart',
          //   //     this.handleTouchStart,
          //   //     { passive: false }
          //   //   );
          //   //   this.state.canvas2.addEventListener(
          //   //     'touchmove',
          //   //     this.handleTouchMove,
          //   //     { passive: false }
          //   //   );
          //   //   this.state.canvas2.addEventListener(
          //   //     'touchend',
          //   //     this.handleTouchEnd,
          //   //     { passive: false }
          //   //   );
          //   // }

          //   //   处理解刨点位数据
          //   //   this.state.markers = [];
          //   //   this.saveMarkers();
          //   //   const markersMap = new Map(
          //   //     this.state.markers.map((marker) => [
          //   //       marker.medicineAtlasImgId,
          //   //       marker,
          //   //     ])
          //   //   );
          //   //   for (const items of this.Pointnewdata) {
          //   //     try {
          //   //       if (items.medicineAtlasImgId != null) {
          //   //         const existingMarker = markersMap.get(
          //   //           items.medicineAtlasImgId
          //   //         );
          //   //         const markingPointsObjects = JSON.parse(items.markingPoints);
          //   //         markingPointsObjects.medicineAtlasImgId =
          //   //           items.medicineAtlasImgId;
          //   //         markingPointsObjects.bsdata[0].markingPointsId =
          //   //           items.markingPointsId;
          //   //         markingPointsObjects.bsdata[0].flag = true;
          //   //         markingPointsObjects.bsdata[0].labels = true;
          //   //         markingPointsObjects.bsdata[0].anatomicStructureName =
          //   //           items.anatomicStructureName;
          //   //         markingPointsObjects.bsdata[0].anatomicStructureId =
          //   //           items.anatomicStructureId;
          //   //         if (existingMarker) {
          //   //           existingMarker.bsdata.push(...markingPointsObjects.bsdata);
          //   //         } else {
          //   //           markersMap.set(
          //   //             items.medicineAtlasImgId,
          //   //             markingPointsObjects
          //   //           );
          //   //         }
          //   //       }
          //   //     } catch (error) {
          //   //       console.error('Error processing item:', items, error);
          //   //     }
          //   //     this.state.markers = Array.from(markersMap.values());
          //   //     // 处理解剖点数据完成

          //   //     // 获取解剖结构数据
          //   //     this.optionsdata = this.jgListdata.map((item) => {
          //   //       // 这一步后面可以删除这是增加开关判断
          //   //       return { ...item, flag: true };
          //   //     });

          //   //     this.anatomicStructurefn();
          //   //     // 处理解剖结构完成
          //   //     // 获取图像大小
          //   //     this.getimgsize();
          //   //     // 开始绘制
          //   //     this.draw('');
          //   //     this.loding = false;
          //   //   }
          // };

          // this.state.img.onerror = (error) => {
          //   console.error('Failed to load image:', error);
          //   this.loding = false;
          // };
        });
      },
      handleResize() {
        if (this.$refs.box) {
          this.hbheight = this.$refs.box.offsetHeight;
          this.hbwidth = this.$refs.box.offsetWidth;

          // 重新设置画布尺寸
          const canvas = document.getElementById('myCanvas');
          if (canvas) {
            canvas.width = this.hbwidth;
            canvas.height = this.hbheight;
          }

          // 重新设置覆盖层画布尺寸
          const overlayCanvas = document.getElementById('overlayCanvas');
          if (overlayCanvas) {
            overlayCanvas.width = this.hbwidth;
            overlayCanvas.height = this.hbheight;
          }

          // 重新加载图片并绘制
          const imgsrcd = this.imgsrc.find(
            (item) => item.medicineAtlasImgId === this.dcomid
          );
          if (imgsrcd) {
            this.state.img.src = this.base + imgsrcd.imgUrl;
            this.state.img.onload = () => {
              this.state.imgWidth = this.state.img.naturalWidth;
              this.state.imgHeight = this.state.img.naturalHeight;
              this.draw('');
            };
          }
        }
      },
      handleKeyDown(event) {
        if (event.key === ' ') {
          this.state.isSpacePressed = true;
        }
      },
      handleKeyUp(event) {
        if (event.key === ' ') {
          this.state.isSpacePressed = false;
        }
      },
      handleTouchStart(event) {
        event.preventDefault();
        if (event.touches.length === 2) {
          this.startX = event.touches[0].clientX;
          this.startY = event.touches[0].clientY;
          this.isSwiping = true;
          this.startTime = Date.now();
        }
      },
      handleTouchMove(event) {
        if (!this.isSwiping) return;
        event.preventDefault();
        const currentX = event.touches[0].clientX;
        const currentY = event.touches[0].clientY;
        const deltaX = currentX - this.startX;
        const deltaY = currentY - this.startY;
        const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        const timeElapsed = Date.now() - this.startTime;
        if (distance > this.threshold) {
          this.hasMoved = true;
          if (
            distance > this.fastSwipeDistance &&
            timeElapsed < this.fastSwipeThreshold
          ) {
            this.isFastSwipe = true;
          }
        }
      },
      handleTouchEnd(event) {
        if (!this.isSwiping) return;
        event.preventDefault();
        this.isSwiping = false;
        if (this.hasMoved) {
          if (this.isFastSwipe) {
            this.handleFastSwipe();
          } else {
            this.handleSlowSwipe();
          }
        }
        this.hasMoved = false;
        this.isFastSwipe = false;
      },
      handleFastSwipe() {
        // const currentIndex = this.findindex()
        if (this.startX > this.$refs.box.offsetWidth / 2) {
          this.tagdcoms('1');
        } else {
          this.tagdcoms('-1');
        }
      },
      handleSlowSwipe() {
        // const currentIndex = this.findindex()
        if (this.startX > this.$refs.box.offsetWidth / 2) {
          this.tagdcoms('1');
        } else {
          this.tagdcoms('-1');
        }
      },
      touchStartHandler(event) {
        if (event.touches.length === 2) {
          this.startX = event.touches[0].clientX;
          this.startY = event.touches[0].clientY;
          this.isSwiping = true;
          this.startTime = Date.now();
        }
      },
      touchMoveHandler(event) {
        if (!this.isSwiping) return;
        const currentX = event.touches[0].clientX;
        const currentY = event.touches[0].clientY;
        const deltaX = currentX - this.startX;
        const deltaY = currentY - this.startY;
        const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        const timeElapsed = Date.now() - this.startTime;
        if (distance > this.threshold) {
          this.hasMoved = true;
          if (
            distance > this.fastSwipeDistance &&
            timeElapsed < this.fastSwipeThreshold
          ) {
            this.isFastSwipe = true;
          }
        }
      },
      touchEndHandler() {
        console.log('event');

        if (!this.isSwiping) return;
        this.isSwiping = false;
        if (this.hasMoved) {
          if (this.isFastSwipe) {
            this.handleFastSwipe();
          } else {
            this.handleSlowSwipe();
          }
        }
        this.hasMoved = false;
        this.isFastSwipe = false;
      },
      startDrag(e) {
        if (!this.tdflag) {
          return;
        }
        console.log('当前拖动标记');
        // 判断是否为触摸事件
        const isTouchEvent = 'touches' in e;

        let clientX, clientY;

        if (isTouchEvent) {
          // 触摸事件
          clientX = e.touches[0].clientX;
          clientY = e.touches[0].clientY;
          e.preventDefault(); // 仅在触摸事件时调用 preventDefault
        } else {
          // 鼠标事件
          clientX = e.clientX;
          clientY = e.clientY;
          if (e.button === 0) {
            e.preventDefault(); // 仅在左键点击时调用 preventDefault
          }
        }

        // 判断是否为左键点击或触摸
        if ((e instanceof MouseEvent && e.button === 0) || isTouchEvent) {
          if (this.tdflag) {
            this.state.isDragging = true;

            // 获取 canvas 的位置和尺寸
            const rect = this.state.canvas.getBoundingClientRect();
            console.log('Canvas rect:', rect); // 输出 rect 检查是否精确

            // 确保在计算开始位置时能处理动态变化
            this.state.startDragX = clientX - rect.left - this.state.imgOffsetX;
            this.state.startDragY = clientY - rect.top - this.state.imgOffsetY;
          }
        }
      },
      handleMouseMove(event) {
        // 判断是否为触摸事件
        const isTouchEvent = 'touches' in event;
        let canvasX, canvasY;

        if (isTouchEvent) {
          // 获取触摸事件的坐标
          const touch = event.touches[0];
          const rect = this.state.canvas.getBoundingClientRect();
          canvasX = touch.clientX - rect.left;
          canvasY = touch.clientY - rect.top;
        } else {
          // 获取鼠标事件的坐标
          canvasX = event.offsetX;
          canvasY = event.offsetY;
        }

        if (this.state.isDragging) {
          this.dragMove(event);
        } else {
          this.checkHover(canvasX, canvasY);
          if (this.state.hoveredMarker) {
            this.draw('搜索');
          } else {
            this.draw('');
          }
        }
      },
      stopDrag() {
        this.state.isDragging = false;
        this.tdflag = false;
      },
      handleWheel(event) {
        event.preventDefault();
        const delta = event.deltaY > 0 ? 1 : -1;
        this.tagdcoms(delta.toString());
      },
      handleCanvasClick(event) {
        let canvasX, canvasY;

        if ('touches' in event) {
          // 触摸事件
          const touch = event.touches[0];
          const rect = this.state.canvas.getBoundingClientRect();
          canvasX = touch.clientX - rect.left;
          canvasY = touch.clientY - rect.top;
          this.checkHover(canvasX, canvasY);
          event.preventDefault();
        } else {
          // 鼠标事件
          canvasX = event.offsetX;
          canvasY = event.offsetY;
        }

        if (this.state.canBiaoZhu) {
          // 计算图像坐标
          // const imgX =
          //   (canvasX -
          //     (this.state.canvas.width / 2 -
          //       (this.state.imgWidth * this.state.imgScale) / 2)) /
          //   this.state.imgScale
          // const imgY =
          //   (canvasY -
          //     (this.state.canvas.height / 2 -
          //       (this.state.imgHeight * this.state.imgScale) / 2)) /
          //   this.state.imgScale
          // this.createMarker(imgX, imgY)
        } else if (this.state.hoveredMarker) {
          this.state.currentMarker = this.state.hoveredMarker;
          this.state.currentText = this.state.hoveredMarker.text || '';
          this.markingPointsId = this.state.hoveredMarker.markingPointsId;

          this.draw(this.state.hoveredMarker);

          // getxqPoint({ markPointsId: this.markingPointsId }).then((res) => {
          //   if (res.code === 200) {
          //     this.visible = false
          //     this.bwstuddata = res.data
          //     // 再次查询点位知识点 中英文对照
          //     getPointjs({ pointName: res.data.pointName }).then((resd) => {
          //       this.bwstuddata.pointNameEng = resd.data.pointNameEng || ''
          //       this.bwstuddata.pointContent = resd.data.pointContent
          //       this.handleClick()
          //     })
          //   }
          // })
        }
      },
      checkHover(x, y) {
        this.state.hoveredMarker = null;
        this.myStyle = 'inherit';

        // 从状态中解构出相关的属性
        const { markers, pointSize, imgScale } = this.state;

        // 合并 bsdata
        const mergedBsdata = markers.filter((item) =>
          item.medicineAtlasImgId.includes(this.dcomid)
        );
        const targetElement = { bsdata: [] };
        targetElement.bsdata = mergedBsdata.flatMap((item) => item.bsdata);

        if (targetElement) {
          // 找到目标标记元素中的标记
          for (let marker of targetElement.bsdata) {
            // 获取画布和上下文
            const canvas = this.state.canvas;
            const ctx = this.state.ctx;

            // 计算缩放后的图像尺寸
            const scaledWidth = this.state.imgWidth * imgScale;
            const scaledHeight = this.state.imgHeight * imgScale;

            // 计算图像在画布上的偏移量
            const xOffset =
              (canvas.width - scaledWidth) / 2 + this.state.imgOffsetX;
            const yOffset =
              (canvas.height - scaledHeight) / 2 + this.state.imgOffsetY;

            // 计算标记的位置
            const markerX = marker.x * imgScale + xOffset;
            const markerY = marker.y * imgScale + yOffset;

            // 检查是否悬停在标记点上
            if (
              Math.hypot(x - markerX, y - markerY) <
              (pointSize / 2) * imgScale * 3
            ) {
              this.state.hoveredMarker = marker;
              this.myStyle = 'pointer';
              return true;
            }

            // 检查是否悬停在文本上
            const text = marker.text || '';
            ctx.font = '12px Arial'; // 根据实际使用的字体进行设置
            const textMetrics = ctx.measureText(text);
            const textWidth = textMetrics.width;

            const textX = marker.textX;
            const textY = marker.textY;
            const textHeight = 14 * imgScale;

            // 计算文本的边界框
            const textBoundingBox = {
              left: textX - textWidth - 100,
              right: textX + textWidth + 100,
              top: textY - textHeight,
              bottom: textY,
            };

            if (
              x >= textBoundingBox.left &&
              x <= textBoundingBox.right &&
              y >= textBoundingBox.top &&
              y <= textBoundingBox.bottom
            ) {
              this.myStyle = 'pointer';
              this.state.hoveredMarker = marker;
              return true;
            }
          }
        }

        // 没有悬停在任何标记、线段或文本上
        this.state.hoveredMarker = null;
        return false;
      },
      dragMove(e) {
        // 判断是否是鼠标事件还是触摸事件
        const clientX =
          e instanceof MouseEvent ? e.clientX : e.touches[0].clientX;
        const clientY =
          e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;

        if (this.state.isDragging) {
          const rect = this.state.canvas.getBoundingClientRect();
          this.state.imgOffsetX = clientX - rect.left - this.state.startDragX;
          this.state.imgOffsetY = clientY - rect.top - this.state.startDragY;
          this.draw('');
        }
      },
      // 可删除此版本用不到
      // createMarker(x, y) {
      //   // 创建新标记的逻辑
      //   const newMarker = {
      //     x,
      //     y,
      //     text: '',
      //     color: this.state.pointColor,
      //     flag: true,
      //     labels: true
      //   }

      //   // 添加到当前图片的标记中
      //   const currentImageMarkers = this.state.markers.find(
      //     (marker) => marker.medicineAtlasImgId === this.dcomid
      //   )

      //   if (currentImageMarkers) {
      //     currentImageMarkers.bsdata.push(newMarker)
      //   } else {
      //     this.state.markers.push({
      //       medicineAtlasImgId: this.dcomid,
      //       bsdata: [newMarker]
      //     })
      //   }

      //   this.saveMarkers()
      //   this.draw('')
      // },
      handleClick() {
        this.visible = true;
      },
      loadMarkers() {
        const savedMarkers = localStorage.getItem('markers');
        if (savedMarkers) {
          this.state.markers = JSON.parse(savedMarkers);
        }
      },
      saveMarkers() {
        localStorage.setItem('markers', JSON.stringify(this.state.markers));
      },
      draw(type) {
        if (!this.state.ctx || !this.state.img || !this.state.canvas) {
          console.warn('Canvas or image not ready');
          return;
        }
        if (this.state.imgWidth == 0) {
          console.warn('Image width is 0');
          return;
        }
        // this.state.canvas ||
        const canvas = this.state.canvas2;
        console.log('当前', this.state.canvas2);

        const ctx = this.state.ctx;
        const img = this.state.img;

        // 清空画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        const scaledWidth = this.state.img.naturalWidth * this.state.imgScale;
        const scaledHeight = this.state.img.naturalHeight * this.state.imgScale;

        // 计算图像在画布上的偏移
        const xOffset =
          (canvas.width - scaledWidth) / 2 + this.state.imgOffsetX;
        const yOffset =
          (canvas.height - scaledHeight) / 2 + this.state.imgOffsetY;

        ctx.save();

        // 应用变换
        ctx.translate(canvas.width / 2, canvas.height / 2);
        if (this.state.flipHorizontal) ctx.scale(-1, 1);
        if (this.state.flipVertical) ctx.scale(1, -1);
        ctx.rotate((this.state.rotation * Math.PI) / 180);
        ctx.translate(-canvas.width / 2, -canvas.height / 2);

        // 绘制图像
        ctx.drawImage(img, xOffset, yOffset, scaledWidth, scaledHeight);

        // 恢复上下文状态为绘制标记做准备
        ctx.restore();
        ctx.save();

        // 重新应用变换
        ctx.translate(canvas.width / 2, canvas.height / 2);
        if (this.state.flipHorizontal) ctx.scale(-1, 1);
        if (this.state.flipVertical) ctx.scale(1, -1);
        ctx.rotate((this.state.rotation * Math.PI) / 180);
        ctx.translate(-canvas.width / 2, -canvas.height / 2);

        const margin = 200; // 从画布边缘的边距
        let textHeight = 16; // 文本高度
        let verticalSpacing = 5; // 文本之间的垂直间隔
        const textMargin = 20; // 文本与边缘的距离

        // 记录所有标记的位置和文本
        this.leftMarkers = [];
        this.rightMarkers = [];

        // 定义绘制标记和文本的函数
        const drawMarkersAndText = (markers, isLeft) => {
          markers.forEach((item) => {
            if (!item.medicineAtlasImgId) return;
            const itemsArray = item.medicineAtlasImgId.split(',').map(Number);

            if (itemsArray.includes(this.dcomid)) {
              item.bsdata.forEach((marker) => {
                const markerX = marker.x * this.state.imgScale + xOffset;
                const markerY = marker.y * this.state.imgScale + yOffset;

                // 划分左右位置数组保存
                const count = this.leftMarkers.filter(
                  (item) => item.flag == true
                ).length;
                const counts = this.rightMarkers.filter(
                  (item) => item.flag == true
                ).length;

                // 根据位置将标记存入对应数组
                if (isLeft) {
                  if (markerX < canvas.width / 2) {
                    if (count > 23) {
                      this.leftMarkers.push(marker);
                    } else {
                      marker.lintextshow = marker.flag;
                      this.leftMarkers.push(marker);
                    }
                  }
                } else {
                  if (markerX >= canvas.width / 2) {
                    if (counts > 23) {
                      marker.lintextshow = false;
                      this.rightMarkers.push(marker);
                    } else {
                      marker.lintextshow = marker.flag;
                      this.rightMarkers.push(marker);
                    }
                  }
                }

                // 绘制标记点
                if (marker.flag) {
                  if (marker.tack) {
                    // 开启大头针
                    ctx.beginPath();

                    // 定义大头针参数
                    const baseSize = this.state.pointSize;
                    const radius = baseSize * 1.5;
                    const height = baseSize * 3;

                    // 绘制顶部圆形
                    ctx.arc(markerX, markerY, radius, Math.PI, 0, false);

                    // 绘制底部尖角
                    ctx.lineTo(markerX, markerY + height);
                    ctx.lineTo(markerX - radius, markerY);

                    // 完成路径
                    ctx.closePath();

                    // 设置样式并填充
                    ctx.fillStyle =
                      marker == this.state.hoveredMarker
                        ? '#409EFF'
                        : '#' + marker.color;
                    ctx.fill();

                    // 如果需要边框
                    ctx.lineWidth = 2;
                    ctx.strokeStyle = 'black';
                    ctx.stroke();
                  } else {
                    // 未开启大头针
                    ctx.fillStyle =
                      marker == this.state.hoveredMarker
                        ? '#409EFF'
                        : '#' + marker.color;

                    if (type == '搜索') {
                      ctx.fillStyle =
                        marker == this.state.hoveredMarker
                          ? 'rgba(255, 0, 0, 1)'
                          : 'rgba(128, 128, 128, 0.5)';
                    }
                    ctx.beginPath();
                    ctx.arc(
                      markerX,
                      markerY,
                      this.state.pointSize / 2,
                      0,
                      2 * Math.PI
                    );
                    ctx.fill();
                  }
                }
              });
            }
          });
        };

        // 绘制左侧和右侧的标记
        drawMarkersAndText(this.state.markers, true);
        drawMarkersAndText(this.state.markers, false);

        // 左右数组优化调整顺序
        this.leftMarkers.sort((a, b) => a.y - b.y);
        this.rightMarkers.sort((a, b) => a.y - b.y);

        // 可用区域的总高度
        const availableHeight = canvas.height - 2 * textMargin - 30;

        // 处理左侧或右侧数据
        const calculateStartYAndHeight = (markers) => {
          const markerCount = markers.length;

          if (markerCount === 0) {
            return { totalTextHeight: 0, startY: textMargin };
          }

          // 计算总文本高度
          let totalTextHeight =
            markerCount * (textHeight + verticalSpacing) - verticalSpacing;

          // 动态调整文本大小和间距
          if (totalTextHeight < availableHeight / 2) {
            const scaleFactor = availableHeight / (2 * totalTextHeight);
            textHeight *= Math.min(scaleFactor, 1.3);
            verticalSpacing *= Math.min(scaleFactor, 1.5);
            totalTextHeight =
              markerCount * (textHeight + verticalSpacing) - verticalSpacing;
          }

          // 计算起始位置
          const startY = Math.max(
            textMargin,
            (availableHeight - totalTextHeight) / 2 + textMargin
          );

          return { totalTextHeight, startY };
        };

        // 计算每个文本的位置
        const calculateTextPositions = (markers, startY) => {
          let yPosition = startY;
          let lastYPosition = startY;
          let lastLineCount = 1;
          let lastText = '';

          markers.forEach((marker) => {
            if (marker.flag) {
              const maxTextWidth = margin;
              ctx.font = `${textHeight}px Arial`;
              let lines = [];
              let currentLine = '';
              for (let i = 0; i < lastText.length; i++) {
                const char = lastText[i];
                const testLine = currentLine + char;
                const testWidth = ctx.measureText(testLine).width;

                if (testWidth > maxTextWidth) {
                  lines.push(currentLine);
                  currentLine = char;
                } else {
                  currentLine = testLine;
                }
              }

              if (currentLine) {
                lines.push(currentLine);
              }

              lastLineCount = lines.length;

              if (yPosition + textHeight > availableHeight) {
                marker.lintextshow = marker === type;
                if (marker.lintextshow) {
                  markers[0].lintextshow = false;
                  marker.textY = markers[0].textY;
                }
              } else {
                marker.lintextshow = true;
                yPosition =
                  lastYPosition +
                  lastLineCount * textHeight +
                  verticalSpacing * lastLineCount;
                marker.textY = yPosition;
              }

              lastYPosition = marker.textY;
              lastText = marker.text;
            }
          });
        };

        // 分别计算左侧和右侧文本位置
        const { startY: leftStartY } = calculateStartYAndHeight(
          this.leftMarkers
        );
        const { startY: rightStartY } = calculateStartYAndHeight(
          this.rightMarkers
        );

        calculateTextPositions(this.leftMarkers, leftStartY);
        calculateTextPositions(this.rightMarkers, rightStartY);

        // 定义绘制文本和线条的函数
        const drawTextAndLines = (markers, isLeft) => {
          markers.forEach((marker, index) => {
            const { text, textY } = marker;
            const markerX = marker.x * this.state.imgScale + xOffset;
            const markerY = marker.y * this.state.imgScale + yOffset;
            const textX = isLeft ? margin : canvas.width - margin;

            if (
              marker.lintextshow &&
              marker.flag &&
              marker.labels &&
              !marker.tack
            ) {
              ctx.strokeStyle =
                marker == this.state.hoveredMarker
                  ? '#409EFF'
                  : '#' + marker.color;
              if (type == '搜索') {
                ctx.strokeStyle =
                  marker == this.state.hoveredMarker
                    ? 'rgba(255, 0, 0, 1)'
                    : 'rgba(128, 128, 128, 0.5)';
              }

              ctx.lineWidth = 1.5;
              ctx.beginPath();
              ctx.moveTo(markerX, markerY);

              // 确定线条结束点
              const lineEndX = isLeft
                ? Math.max(textX, margin + 20)
                : Math.min(textX, canvas.width - margin - 20);
              ctx.lineTo(lineEndX, textY);
              ctx.stroke();

              // 判断左右
              if (isLeft) {
                const horizontalLineLength = 10;
                ctx.lineTo(lineEndX - horizontalLineLength, textY);
                const verticalLineHeight = 5;
                ctx.lineTo(
                  lineEndX - horizontalLineLength,
                  textY - 10 - verticalLineHeight
                );
                ctx.stroke();
              } else {
                const horizontalLineLength = 10;
                ctx.lineTo(lineEndX + horizontalLineLength, textY);
                const verticalLineHeight = 5;
                ctx.lineTo(
                  lineEndX + horizontalLineLength,
                  textY - 10 - verticalLineHeight
                );
                ctx.stroke();
              }

              // 计算文本换行
              const maxTextWidth = margin;
              let lineY = textY;
              let lines = [];
              let currentLine = '';
              for (let i = 0; i < text.length; i++) {
                const char = text[i];
                const testLine = currentLine + char;
                const testWidth = ctx.measureText(testLine).width;

                if (testWidth > maxTextWidth) {
                  lines.push(currentLine);
                  currentLine = char;
                } else {
                  currentLine = testLine;
                }
              }

              if (currentLine) {
                lines.push(currentLine);
              }

              // 绘制每一行文本
              lines.forEach((line, lineIndex) => {
                ctx.fillStyle =
                  marker == this.state.hoveredMarker
                    ? '#409EFF'
                    : '#' + marker.color;
                if (type == '搜索') {
                  ctx.fillStyle =
                    marker == this.state.hoveredMarker
                      ? 'rgba(255, 0, 0, 1)'
                      : 'rgba(128, 128, 128, 0.5)';
                }

                ctx.textAlign = isLeft ? 'right' : 'left';
                ctx.font = `${textHeight}px Arial`;

                const adjustedTextY =
                  lineY + lineIndex * (textHeight + verticalSpacing);
                if (this.state.showText) {
                  if (marker.userText) {
                    ctx.fillText(
                      line + ' / ' + marker.userText || '',
                      textX,
                      adjustedTextY
                    );
                  } else {
                    ctx.fillText(line, textX, adjustedTextY);
                  }
                } else {
                  ctx.fillText(
                    marker.userText || index + 1,
                    textX,
                    adjustedTextY
                  );
                }
              });

              // 更新状态
              this.state.markers.forEach((item) => {
                if (!item.medicineAtlasImgId) return;
                const itemsArray = item.medicineAtlasImgId
                  .split(',')
                  .map(Number);
                if (itemsArray.includes(this.dcomid)) {
                  item.bsdata.forEach((markers) => {
                    if (markers.markingPointsId == marker.markingPointsId) {
                      markers.textX = textX;
                      markers.textY = lineY;
                    }
                  });
                }
              });
            }
          });
        };

        // 绘制左侧和右侧的文本和线条
        drawTextAndLines(this.leftMarkers, true);
        drawTextAndLines(this.rightMarkers, false);

        // 恢复上下文状态
        ctx.restore();
        this.loding = false;
      },
      zoomIn() {
        this.state.imgScale = Math.min(
          3,
          this.state.imgScale + this.state.zoomStep
        );
        this.draw('');
      },
      zoomOut() {
        this.state.imgScale = Math.max(
          0.1,
          this.state.imgScale - this.state.zoomStep
        );
        this.draw('');
      },
      reset() {
        this.getimgsize();

        this.state.imgOffsetX = 0;
        this.state.imgOffsetY = 0;
        this.state.rotation = 0;
        this.state.flipHorizontal = false;
        this.state.flipVertical = false;
        this.draw('');
      },
      toggleLinesAndText() {
        this.state.showLinesAndText = !this.state.showLinesAndText;
        this.draw('');
      },
      flipHorizontald() {
        this.state.flipHorizontal = !this.state.flipHorizontal;
        this.draw('');
      },
      flipVerticald() {
        this.state.flipVertical = !this.state.flipVertical;
        this.draw('');
      },
      rotate90() {
        this.state.rotation = (this.state.rotation + 90) % 360;
        this.draw('');
      },
      rotateMinus90() {
        this.state.rotation = (this.state.rotation - 90) % 360;
        this.draw('');
      },
      anatomicStructurefn() {
        this.anatomicStructure = [];
        this.optionsdata.forEach((items) => {
          this.state.markers.some((item) => {
            if (!item.medicineAtlasImgId) {
              return;
            }

            const itemsArray = item.medicineAtlasImgId.split(',').map(Number);
            if (itemsArray.includes(this.dcomid)) {
              item.bsdata.forEach((itemd) => {
                if (itemd.anatomicStructureId == items.anatomicStructureId) {
                  // 先检查是否已存在
                  const exists = this.anatomicStructure.some(
                    (a) => a.anatomicStructureId === items.anatomicStructureId
                  );

                  if (!exists) {
                    this.anatomicStructure.push(items);
                  }
                }
              });
            }
            return false;
          });
        });
        // console.log(
        //   '处理完成的数据',
        //   this.anatomicStructure,
        //   this.optionsdata,
        //   this.state.markers
        // );
      },
      flagfn(item) {
        return this.state.markers.some((marker) => {
          const itemsArray = marker.medicineAtlasImgId.split(',').map(Number);
          if (itemsArray.includes(this.dcomid)) {
            return marker.bsdata.some(
              (itemd) => itemd.anatomicStructureId === item.anatomicStructureId
            );
          }
          return false;
        });
      },
      changecs(item) {
        console.log('关联解剖结构测试', this.anatomicStructure, item);
        this.state.markers.some((marker) => {
          marker.bsdata.some((itemd) => {
            if (itemd.anatomicStructureId == item.anatomicStructureId) {
              itemd.flag = item.flag;
            }
          });
        });

        // 判断是否存在 flag 为 false 的项
        this.allflag = !this.anatomicStructure.some(
          (item) => item.flag === false
        );

        this.draw('');
      },
      changeimgclassfn(name) {
        this.classificationName = name;
        this.imgsrc = [];
        this.imgsrcs.forEach((item) => {
          if (this.classificationName === item.imgClassificationName) {
            this.imgsrc.push(item);
          }
        });

        if (name === '全部') {
          this.imggroupname = '全部';
          this.imgsrc = this.imgsrcs;
          this.dcomid = this.imgsrc[0].medicineAtlasImgId;
          this.tagdcom(this.dcomid, '');
          return;
        }

        if (this.imggroupname !== '全部') {
          this.changeimggroupfn(this.imggroupname, false);
        }

        this.dcomid = this.imgsrc[0].medicineAtlasImgId;
        this.tagdcom(this.dcomid, '');
      },
      changeimggroupfn(name, flag) {
        if (name === '全部' && flag) {
          this.imggroupname = '全部';
          this.changeimgclassfn(this.classificationName);
          return;
        }

        this.imggroupname = name;
        const item = this.imggroup.find(
          (img) => img.typeName === this.imggroupname
        );

        const imgsrcsd = item;
        const imgsrcmw = this.imgsrc;
        this.imgsrc = [];

        // 判断解剖面是默认或者全选状态的时候默认选择第一个选项
        if (this.classificationName === '全部') {
          this.classificationName = this.imgclassdata[0].classificationName;
        }

        // 判断完成
        if (this.classificationName !== '') {
          imgsrcsd.typeImg.forEach((itemd) => {
            if (
              this.classificationName === itemd.imgClassificationName &&
              this.imggroupname === itemd.typeName
            ) {
              this.imgsrc.push(itemd);
            }
          });
        } else {
          this.imgsrc = imgsrcsd.typeImg;
        }

        if (this.imgsrc.length > 0) {
          this.dcomid = this.imgsrc[0].medicineAtlasImgId;
          this.tagdcom(this.dcomid, '');
        } else {
          console.log('当前图像没有T2', this.imgsrc);
          this.imgsrc = imgsrcmw;

          this.$message.warning('暂无图像，请更换其他解剖面后再选择加权！');
          this.imggroupname = '全部';
        }
      },
      findindex() {
        return this.imgsrc.findIndex(
          (item) => item.medicineAtlasImgId === this.dcomid
        );
      },
      // 封装
      getimgsize() {
        const canvas = this.state.canvas;
        const aspectRatio =
          this.state.img.naturalWidth / this.state.img.naturalHeight;
        const canvasAspectRatio = canvas.width / canvas.height;
        // 设置最大宽度和高度
        const maxWidth = canvas.width * 0.99; // 画布宽度的99.9%
        const maxHeight = canvas.height * 0.99; // 画布高度的99.9%

        if (canvasAspectRatio > aspectRatio) {
          this.state.imgScale = Math.min(
            maxHeight / this.state.img.naturalHeight,
            1
          );
        } else {
          this.state.imgScale = Math.min(
            maxWidth / this.state.img.naturalWidth,
            1
          );
        }
      },
      tagdcom(id, type) {
        this.getimgsize();
        if (id) {
          this.dcomid = id;
          localStorage.setItem('dcomid', id);
          console.log('切换了id', this.dcomid);
        }
        const imgsrcd = this.imgsrc.find(
          (item) => item.medicineAtlasImgId === this.dcomid
        );
        if (imgsrcd) {
          this.state.img.src = this.base + imgsrcd.imgUrl;
          this.state.img.onload = () => {
            this.state.imgWidth = this.state.img.naturalWidth;
            this.state.imgHeight = this.state.img.naturalHeight;
            if (type == '搜索') {
              this.draw('搜索');
            } else {
              this.draw('');
            }
          };
        }
      },
      tagdcoms(type) {
        const currentIndex = this.findindex();
        let newIndex;
        if (type === '1') {
          newIndex = (currentIndex + 1) % this.imgsrc.length;
        } else {
          newIndex =
            (currentIndex - 1 + this.imgsrc.length) % this.imgsrc.length;
        }
        this.tagdcom(this.imgsrc[newIndex].medicineAtlasImgId, '');
      },
      getScrollPosition(event) {
        const scrollLeft = event.target.scrollLeft;
        const scrollWidth = event.target.scrollWidth;
        const clientWidth = event.target.clientWidth;
        if (scrollLeft + clientWidth >= scrollWidth) {
          this.tagdcoms('1');
        } else if (scrollLeft === 0) {
          this.tagdcoms('-1');
        }
      },
      goback() {
        window.close();
        // this.$router.go(-1)
      },

      toggleTextButton() {
        this.draw('');
      },
      pzfn() {
        this.isCanvasVisible = this.pzshow;
        if (this.pzshow) {
          this.currentMode = 'drawing';
          this.currentCursorStyle = 'crosshair';

          this.$nextTick(() => {
            const myCanvas = document.getElementById('myCanvas');
            const overlayCanvas = document.getElementById('overlayCanvas');

            // 获取画布上下文
            this.context = myCanvas.getContext('2d', {
              willReadFrequently: true,
            });
            this.overlayContext = overlayCanvas.getContext('2d', {
              willReadFrequently: true,
            });

            // 保存初始状态
            this.canvasHistory.push(
              this.overlayContext.getImageData(
                0,
                0,
                overlayCanvas.width,
                overlayCanvas.height
              )
            );
          });
        } else {
          this.currentMode = null;
          this.currentCursorStyle = 'inherit';
          // 清除画布内容
          const overlayCanvas = this.$refs.overlayCanvas;
          if (overlayCanvas) {
            const ctx = overlayCanvas.getContext('2d');
            ctx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);
          }
        }
      },
      jubu() {
        const matchingItems = this.state.markers.filter((item) =>
          item.medicineAtlasImgId.includes(this.dcomid)
        );

        matchingItems.forEach((item) => {
          item.bsdata.forEach((items) => {
            items.labels = !this.jubushow; // 切换标签状态
          });
        });

        this.saveMarkers();
        this.draw('');

        const canvasContainer = document.getElementById('canvasContainer');
        if (!canvasContainer) return; // 确保容器存在

        // 确保父容器是相对定位
        canvasContainer.style.position = 'relative';

        // 检查是否已有子画布，若存在则移除并退出
        const existingOverlayCanvas = canvasContainer.querySelector(
          'canvas[data-role="overlay"]'
        );
        if (existingOverlayCanvas) {
          canvasContainer.removeChild(existingOverlayCanvas);
          canvasContainer
            .querySelectorAll('div[data-role="resize-handle"]')
            .forEach((circle) => circle.remove());
          return; // 不再执行后续代码
        }

        // 创建并设置新的子 canvas
        const overlayCanvas = document.createElement('canvas');
        overlayCanvas.width = 80;
        overlayCanvas.height = 80;
        overlayCanvas.style.cssText = `
            border: 1px solid ${
              this.atlasTypeName == '插画' ? 'red' : '#ffffff'
            };
            position: absolute;
            z-index: 10;
            left: 750px; /* 初始位置 */
            top: 350px; /* 初始位置 */
            cursor: move;
          `;
        overlayCanvas.setAttribute('data-role', 'overlay'); // 添加标识以便后续查找
        canvasContainer.appendChild(overlayCanvas);

        // 当前画布状态
        let currentState = {
          width: overlayCanvas.width,
          height: overlayCanvas.height,
          left: parseFloat(overlayCanvas.style.left),
          top: parseFloat(overlayCanvas.style.top),
        };

        // 是否在拖动模式
        let isDragging = false;
        let dragOffsetX = 0;
        let dragOffsetY = 0;

        // 判断是否为触摸设备
        const isTouchDevice =
          'ontouchstart' in window &&
          window.matchMedia('(pointer: coarse)').matches;

        // 画布拖动逻辑
        const startDragx = (e) => {
          e.preventDefault();
          isDragging = true;
          const clientX = isTouchDevice ? e.touches[0].clientX : e.clientX;
          const clientY = isTouchDevice ? e.touches[0].clientY : e.clientY;
          dragOffsetX = clientX - overlayCanvas.offsetLeft;
          dragOffsetY = clientY - overlayCanvas.offsetTop;

          const onMove = (moveEvent) => {
            if (!isDragging) return;
            const newX =
              (isTouchDevice
                ? moveEvent.touches[0].clientX
                : moveEvent.clientX) - dragOffsetX;
            const newY =
              (isTouchDevice
                ? moveEvent.touches[0].clientY
                : moveEvent.clientY) - dragOffsetY;
            currentState.left = newX;
            currentState.top = newY;

            overlayCanvas.style.left = `${newX}px`;
            overlayCanvas.style.top = `${newY}px`;

            updateControlPoints();
            updateMarkers(); // 更新标记点状态
          };

          const stopDragx = () => {
            isDragging = false;
            window.removeEventListener(
              isTouchDevice ? 'touchmove' : 'mousemove',
              onMove
            );
            window.removeEventListener(
              isTouchDevice ? 'touchend' : 'mouseup',
              stopDragx
            );
            this.draw(''); // 拖动完成后更新画布
          };

          window.addEventListener(
            isTouchDevice ? 'touchmove' : 'mousemove',
            onMove
          );
          window.addEventListener(
            isTouchDevice ? 'touchend' : 'mouseup',
            stopDragx
          );
        };

        overlayCanvas.addEventListener(
          isTouchDevice ? 'touchstart' : 'mousedown',
          startDragx
        );

        // 更新圆点位置
        const updateControlPoints = () => {
          const canvasRect = overlayCanvas.getBoundingClientRect();
          const containerRect = canvasContainer.getBoundingClientRect();

          const controlPoints = [
            {
              x: canvasRect.left - containerRect.left,
              y: canvasRect.top - containerRect.top,
            }, // 左上角
            {
              x: canvasRect.left - containerRect.left + canvasRect.width / 2,
              y: canvasRect.top - containerRect.top,
            }, // 顶边中心
            {
              x: canvasRect.right - containerRect.left,
              y: canvasRect.top - containerRect.top,
            }, // 右上角
            {
              x: canvasRect.left - containerRect.left,
              y: canvasRect.top - containerRect.top + canvasRect.height / 2,
            }, // 左边中心
            {
              x: canvasRect.right - containerRect.left,
              y: canvasRect.top - containerRect.top + canvasRect.height / 2,
            }, // 右边中心
            {
              x: canvasRect.left - containerRect.left,
              y: canvasRect.bottom - containerRect.top,
            }, // 左下角
            {
              x: canvasRect.left - containerRect.left + canvasRect.width / 2,
              y: canvasRect.bottom - containerRect.top,
            }, // 底边中心
            {
              x: canvasRect.right - containerRect.left,
              y: canvasRect.bottom - containerRect.top,
            }, // 右下角
          ];

          controlHandles.forEach((circle, index) => {
            circle.style.left = `${controlPoints[index].x - 5}px`;
            circle.style.top = `${controlPoints[index].y - 5}px`;
          });
        };

        // 更新标记点状态
        const updateMarkers = () => {
          const scaledWidth = this.state.img.naturalWidth * this.state.imgScale;
          const scaledHeight =
            this.state.img.naturalHeight * this.state.imgScale;

          const canvasOffsetX =
            (this.state.canvas.width - scaledWidth) / 2 + this.state.imgOffsetX;
          const canvasOffsetY =
            (this.state.canvas.height - scaledHeight) / 2 +
            this.state.imgOffsetY;

          const localCanvasLeft = currentState.left - canvasOffsetX;
          const localCanvasTop = currentState.top - canvasOffsetY;
          const localCanvasRight = localCanvasLeft + currentState.width;
          const localCanvasBottom = localCanvasTop + currentState.height;

          matchingItems.forEach((item) => {
            item.bsdata.forEach((marker) => {
              const scaledMarkerX = marker.x * this.state.imgScale;
              const scaledMarkerY = marker.y * this.state.imgScale;

              const isInside =
                scaledMarkerX >= localCanvasLeft &&
                scaledMarkerX <= localCanvasRight &&
                scaledMarkerY >= localCanvasTop &&
                scaledMarkerY <= localCanvasBottom;

              marker.labels = isInside; // 根据是否在区域内更新状态
            });
          });
        };

        // 添加圆点
        const controlHandles = [];
        const createCircle = (index) => {
          const circle = document.createElement('div');
          circle.style.cssText = `
              width: 10px;
              height: 10px;
              background-color: #ff0000;
              border-radius: 50%;
              position: absolute;
              z-index: 15;
              cursor: pointer;
            `;
          circle.setAttribute('data-index', index);
          circle.setAttribute('data-role', 'resize-handle');
          canvasContainer.appendChild(circle);
          return circle;
        };

        for (let i = 0; i < 8; i++) {
          const circle = createCircle(i);
          controlHandles.push(circle);
          let isResizing = false;

          circle.addEventListener(
            isTouchDevice ? 'touchstart' : 'mousedown',
            (e) => {
              e.preventDefault();
              e.stopPropagation(); // 防止触发拖动事件
              isResizing = true;

              const startX = isTouchDevice ? e.touches[0].clientX : e.clientX;
              const startY = isTouchDevice ? e.touches[0].clientY : e.clientY;

              const startState = { ...currentState };

              const onResizeMove = (moveEvent) => {
                if (!isResizing) return;

                const dx =
                  (isTouchDevice
                    ? moveEvent.touches[0].clientX
                    : moveEvent.clientX) - startX;
                const dy =
                  (isTouchDevice
                    ? moveEvent.touches[0].clientY
                    : moveEvent.clientY) - startY;

                switch (i) {
                  case 0: // 左上角
                    currentState.width = startState.width - dx;
                    currentState.height = startState.height - dy;
                    currentState.left = startState.left + dx;
                    currentState.top = startState.top + dy;
                    break;
                  case 1: // 顶边中心
                    currentState.height = startState.height - dy;
                    currentState.top = startState.top + dy;
                    break;
                  case 2: // 右上角
                    currentState.width = startState.width + dx;
                    currentState.height = startState.height - dy;
                    currentState.top = startState.top + dy;
                    break;
                  case 3: // 左边中心
                    currentState.width = startState.width - dx;
                    currentState.left = startState.left + dx;
                    break;
                  case 4: // 右边中心
                    currentState.width = startState.width + dx;
                    break;
                  case 5: // 左下角
                    currentState.width = startState.width - dx;
                    currentState.height = startState.height + dy;
                    currentState.left = startState.left + dx;
                    break;
                  case 6: // 底边中心
                    currentState.height = startState.height + dy;
                    break;
                  case 7: // 右下角
                    currentState.width = startState.width + dx;
                    currentState.height = startState.height + dy;
                    break;
                }

                overlayCanvas.style.width = `${currentState.width}px`;
                overlayCanvas.style.height = `${currentState.height}px`;
                overlayCanvas.style.left = `${currentState.left}px`;
                overlayCanvas.style.top = `${currentState.top}px`;

                updateControlPoints();
                updateMarkers();
              };

              const stopResize = () => {
                isResizing = false;
                window.removeEventListener(
                  isTouchDevice ? 'touchmove' : 'mousemove',
                  onResizeMove
                );
                window.removeEventListener(
                  isTouchDevice ? 'touchend' : 'mouseup',
                  stopResize
                );
                this.draw(''); // 调整完成后更新画布
              };

              window.addEventListener(
                isTouchDevice ? 'touchmove' : 'mousemove',
                onResizeMove
              );
              window.addEventListener(
                isTouchDevice ? 'touchend' : 'mouseup',
                stopResize
              );
            }
          );
        }

        updateControlPoints(); // 初始化控制点位置
        updateMarkers(); // 初始化标记点状态
      },
      handleCancelst() {
        this.visiblest = false;
      },

      enableDrawingMode() {
        this.currentMode = 'drawing';
        this.currentCursorStyle = 'crosshair';
        this.selectedTool = 'drawing';
        this.isEraserMode = false; // 确保橡皮擦模式关闭
        this.brushColor = '#ff0000'; // 重置画笔颜色为红色
      },
      enableTextMode() {
        this.currentMode = 'text';
        this.currentCursorStyle = 'text';
        this.selectedTool = 'text';
      },
      toggleEraser() {
        this.isEraserMode = !this.isEraserMode;
        this.brushColor = this.isEraserMode ? '#ffffff' : '#ff0000';
        this.selectedTool = this.isEraserMode ? 'eraser' : null;
        this.currentCursorStyle = this.isEraserMode
          ? "url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path fill='%23ffffff' d='M15.14,3C14.63,3 14.12,3.2 13.73,3.59L2.59,14.73C1.81,15.5 1.81,16.77 2.59,17.54L5.03,20H12.69L21.41,11.27C22.19,10.5 22.19,9.23 21.41,8.46L16.86,3.59C16.46,3.2 15.95,3 15.14,3M17,7L19,9L15,13L13,11L17,7M3,21L5,19L7,21L9,19L11,21L13,19L15,21L17,19L19,21L21,19L19,17L21,15L19,13L21,11L19,9L21,7L19,5L21,3L19,5L17,3L15,5L13,3L11,5L9,3L7,5L5,3L7,5L5,7L3,9L5,11L3,13L5,15L3,17L5,19L3,21Z'/></svg>\") 12 12, auto"
          : 'crosshair';
      },
      startDrawing(event) {
        if (this.currentMode !== 'drawing' && !this.isEraserMode) return;
        this.isDrawing = true;
        this.draws(event);

        // 保存当前状态到历史记录
        const canvas = document.getElementById('overlayCanvas');
        const currentState = this.overlayContext.getImageData(
          0,
          0,
          canvas.width,
          canvas.height
        );
        this.canvasHistory.push(currentState);
      },
      stopDrawing() {
        this.isDrawing = false;
        this.overlayContext.beginPath();
      },
      draws(event) {
        event.preventDefault();
        if (!this.isDrawing || !this.overlayContext) return;

        const rect = document
          .getElementById('overlayCanvas')
          .getBoundingClientRect();

        let x, y;

        // 判断是否是触摸事件
        if (event.touches && event.touches.length > 0) {
          x = event.touches[0].clientX - rect.left;
          y = event.touches[0].clientY - rect.top;
        } else {
          x = event.clientX - rect.left;
          y = event.clientY - rect.top;
        }

        if (this.isEraserMode) {
          // 如果是橡皮擦模式，擦除线段
          this.erase(x, y);
        } else {
          // 否则是绘制模式
          this.overlayContext.lineWidth = this.brushSize;
          this.overlayContext.lineCap = 'round';
          this.overlayContext.strokeStyle = this.brushColor;

          this.overlayContext.lineTo(x, y);
          this.overlayContext.stroke();
          this.overlayContext.beginPath();
          this.overlayContext.moveTo(x, y);
        }
      },
      erase(x, y, tolerance = 10) {
        const canvas = document.getElementById('overlayCanvas');

        // 获取画布数据
        const imageData = this.overlayContext.getImageData(
          0,
          0,
          canvas.width,
          canvas.height
        );
        const data = imageData.data;

        // 获取擦除区域的像素数据
        const eraseRadius = this.brushSize + tolerance; // 扩大半径以确保擦除范围足够

        // 循环遍历每个像素
        for (let i = 0; i < data.length; i += 4) {
          const px = (i / 4) % canvas.width;
          const py = Math.floor(i / 4 / canvas.width);
          const dx = px - x;
          const dy = py - y;

          // 计算当前像素点到鼠标点的距离
          if (Math.sqrt(dx * dx + dy * dy) < eraseRadius) {
            data[i] = 255; // R
            data[i + 1] = 255; // G
            data[i + 2] = 255; // B
            data[i + 3] = 0; // A (透明度)
          }
        }

        // 更新画布
        this.overlayContext.putImageData(imageData, 0, 0);
      },
      redrawCanvas() {
        const canvas = document.getElementById('overlayCanvas');
        if (canvas) {
          this.overlayContext.clearRect(0, 0, canvas.width, canvas.height);
        }

        if (this.canvasHistory.length > 0) {
          // 恢复最后的画布状态
          const lastState = this.canvasHistory[this.canvasHistory.length - 1];
          this.overlayContext.putImageData(lastState, 0, 0);
        }
      },
      undo() {
        if (this.canvasHistory.length > 0) {
          // 保存当前状态到重做栈
          const canvas = document.getElementById('overlayCanvas');
          const currentState = this.overlayContext.getImageData(
            0,
            0,
            canvas.width,
            canvas.height
          );
          this.redoHistory.push(currentState);

          // 弹出最近的状态
          const lastState = this.canvasHistory.pop();

          // 清除当前画布
          this.overlayContext.clearRect(0, 0, canvas.width, canvas.height);

          // 恢复状态并立即重绘
          this.overlayContext.putImageData(lastState, 0, 0);
          this.draw('');
        }
      },
      redo() {
        if (this.redoHistory.length > 0) {
          // 保存当前状态到撤销栈
          const canvas = document.getElementById('overlayCanvas');
          const currentState = this.overlayContext.getImageData(
            0,
            0,
            canvas.width,
            canvas.height
          );
          this.canvasHistory.push(currentState);

          // 获取最近的还原状态
          const lastUndoState = this.redoHistory.pop();

          // 清除当前画布
          this.overlayContext.clearRect(0, 0, canvas.width, canvas.height);

          // 恢复状态并立即重绘
          this.overlayContext.putImageData(lastUndoState, 0, 0);
          this.draw('');
        }
      },
      showTextInput(event) {
        if (this.currentMode != 'text') return;

        // const rect = document
        //   .getElementById('overlayCanvas')
        //   .getBoundingClientRect()
        // const x = event.clientX - rect.left
        // const y = event.clientY - rect.top

        // 设置输入框的位置
        this.inputStyle = {
          position: 'absolute',
          left: `${event.clientX - 10}px`,
          top: `${event.clientY - 65}px`,
        };
        this.customText = ''; // 清空输入框内容
        this.showInput = true; // 显示输入框

        // 使用 nextTick 确保输入框显示后立即获得焦点
        this.$nextTick(() => {
          const inputElement = document.querySelector('.text-input');
          if (inputElement) {
            inputElement.focus(); // 设置焦点
          }
        });
      },
      addTextMarker(text, x, y) {
        if (!this.overlayContext) return;

        this.overlayContext.font = '20px Arial';
        this.overlayContext.fillStyle = 'red';
        this.overlayContext.fillText(text, x, y);
      },
      addTextMarkerOnBlur() {
        if (this.customText) {
          this.addTextMarker(
            this.customText,
            parseFloat(this.inputStyle.left),
            parseFloat(this.inputStyle.top)
          );
        }
        this.showInput = false;
      },
      addTextMarkerOnEnter(event) {
        if (event.key === 'Enter' && this.customText) {
          this.addTextMarker(
            this.customText,
            parseFloat(this.inputStyle.left),
            parseFloat(this.inputStyle.top)
          );
          this.showInput = false;
        }
      },
      handleInputBlur() {
        this.isInputActive = false;
        this.addTextMarkerOnBlur();
      },
      downloadImage() {
        this.currentMode = 'download';
        const myCanvas = document.getElementById('myCanvas');
        const overlayCanvas = document.getElementById('overlayCanvas');

        const combinedCanvas = document.createElement('canvas');
        combinedCanvas.width = this.hbwidth;
        combinedCanvas.height = this.hbheight;
        const ctx = combinedCanvas.getContext('2d', {
          willReadFrequently: true,
        });
        // 设置背景颜色为黑色
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, combinedCanvas.width, combinedCanvas.height);
        // 绘制原始画布的内容
        ctx.drawImage(myCanvas, 0, 0);
        // 绘制标记画布的内容
        ctx.drawImage(overlayCanvas, 0, 0);

        try {
          // 将合成的画布转换为数据URL
          const imageDataURL = combinedCanvas.toDataURL('image/png');
          // 创建下载链接并触发下载
          const link = document.createElement('a');
          link.href = imageDataURL;
          link.download = 'combined_image.png';
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        } catch (error) {
          console.error('Error exporting canvas: ', error);
        }
      },

      clearOverlay() {
        this.currentMode = 'delel';
        this.selectedTool = 'clear';
        const overlayCanvas = document.getElementById('overlayCanvas');
        if (overlayCanvas) {
          const overlayContext = overlayCanvas.getContext('2d', {
            willReadFrequently: true,
          });
          overlayContext.clearRect(
            0,
            0,
            overlayCanvas.width,
            overlayCanvas.height
          );
        }
      },
      handleSearch(query) {
        this.optionsselect = [];
        this.state.markers.forEach((item) => {
          item.bsdata.forEach((items) => {
            if (items.text.toLowerCase().includes(query.toLowerCase())) {
              this.optionsselect.push({
                markingPointsId: items.markingPointsId,
                text: items.text,
              });
            }
          });
        });
      },
      changeselect(e) {
        // 重置一下当前选择
        this.changeimgclassfn('全部');
        this.changeimggroupfn('全部', true);
        this.state.markers.forEach((item) => {
          item.bsdata.forEach((items) => {
            if (items.markingPointsId == e) {
              let firstPart = item.medicineAtlasImgId.split(',')[0];
              this.state.hoveredMarker = items;
              this.tagdcom(Number(firstPart), '搜索');
            }
          });
        });
      },
      changecsd() {
        console.log('当前全选了');
        this.state.markers.forEach((item) => {
          item.bsdata.forEach((items) => {
            items.flag = this.allflag;
          });
        });

        this.anatomicStructure.forEach((jg) => {
          jg.flag = this.allflag;
        });
        this.saveMarkers();
        this.draw('');
      },
    },
  };
</script>

<style scoped>
  .overlayCanvastooitems {
    background: #409eff;
  }
  .text-input-container {
    /* 输入框的容器样式 */
    z-index: 99;
  }

  .text-input {
    padding: 5px;
    border: 1px solid #ccc;
  }
  #overlayCanvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2; /* 画板层 */
  }
  .bjbox {
    width: 100%;
    height: 172px;
  }
  .bjbox img {
    width: 100%;
    height: 172px;
  }
  .mainboxgj {
    display: flex;
    width: 100%;
    height: 100%;
  }
  .maintopbox {
    width: 100%;
    /* height: 45px; */
    height: 4.5%;
    background: linear-gradient(180deg, #504f5d 0%, #212227 100%);
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    position: relative;
  }
  .mainbottombox {
    width: 100%;
    height: 95.5%;
    display: flex;
  }
  .mainbottomboxleft {
    display: flex;
    flex-direction: column;
    width: 82.5%;
    height: 100%;
    overflow: hidden;
  }
  .mainsera {
    position: absolute;
    left: 0px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .box {
    margin: 0 auto;
    width: 100%;
    height: 84.5%;
    position: relative;
    overflow: hidden;
  }
  .lboxmain {
    display: flex;
    background-color: #484c56;
    height: 10.5%;
    overflow: hidden;
  }
  .mainsers {
    display: flex;
    align-items: center;
    padding-left: 15px;
    width: 100%;
    height: 5%;
    overflow: hidden;
    color: #333333;
    font-size: 14px;
    background: linear-gradient(180deg, #cfd3d9 0%, #b0b3b8 100%);
  }
  .maintoptitle {
    font-size: 20px;
    color: #ffffff;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 54px;
  }
  .maintopright {
    display: flex;
    position: absolute;
    right: 354px;
    top: 50%;
    transform: translate(0, -50%);
  }
  .czmainitem {
    cursor: pointer;
    margin: 0 5px;
  }
  .czmainitem img {
    width: 35px;
    height: 36px;
  }
  .gnbocdtop .arco-btn {
    margin: 0;
    /* margin: 5px 10px; */
  }
  .gnbocdtop {
    width: 100%;
    height: 15%;

    border-bottom: 2px solid #5a5a5a;
    display: flex;
    flex-direction: column;
    align-content: center;
    justify-content: center;
    overflow-y: auto;
  }
  .gnbocd {
    width: 100%;
    height: 75%;
    overflow: hidden;
    overflow-y: auto;

    display: flex;
    flex-direction: column;
  }
  .gnbocdname {
    font-size: 20px;
    color: #ffffff;
    padding: 10px;
  }
  .gnbottom {
    height: 90px;
    width: 161px;
    z-index: 9;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
  #canvasContainer {
    position: relative;
  }

  .mentox {
    font-size: 14px;
    color: #fff;
    margin: 6px 0;
  }
  .mentoxs {
    width: 141px;
    height: 40px;
    background: #34343e;
    box-shadow: inset 2px 2px 4px 0px rgba(0, 0, 0, 0.6),
      inset -2px -2px 4px 0px rgba(0, 0, 0, 0.6);
    border-radius: 4px 4px 4px 4px;
    border: 0px solid rgba(255, 255, 255, 0.5);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .mentoxs span {
    font-size: 20px;
    color: #ffffff;
    margin: 0px 5px;
    display: block;
  }
  .mentoxs img {
    width: 31px;
    height: 31px;
  }
  .boxs {
    width: 300px;
    display: flex;
    flex-direction: column;
    align-content: center;
    justify-content: center;
  }
  .zsdkz {
    font-size: 18px;
    color: #ffffff;
    line-height: 30px;
    padding: 5px 10px;
  }
  .boxsitem {
    width: 130px;
    height: 130px;
    margin: 10px 25px;
    background: black;
  }
  .boxsitems {
    text-align: center;
  }

  .bocd {
    /* margin: 10px; */
    /* width: 20%;
         height: 100%; */
    width: 335px;
    height: 905px;
    background: linear-gradient(180deg, #727786 0%, #484c56 1%);
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .mainboxleft {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  .lbox {
    width: 100%;
    height: 100%;
    display: flex;
    overflow: hidden;
    overflow-x: auto;
    white-space: nowrap;
    background-color: #484c56;

    /* border-top: 2px solid #5a5a5a; */
  }

  .lboxitem {
    width: 70px;
    margin: 0px 1px;
    /* height: 70px; */
    cursor: pointer;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .lboxitem img {
    width: 55px;
    height: 55px;
  }

  .msx {
    height: 100px;
    width: 2px;
    background-color: #409eff;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  .gnbocd::-webkit-scrollbar {
    width: 5px;
    height: 5px;
  }

  .gnbocd::-webkit-scrollbar-track {
    width: 6px;
    background: rgba(#101f1c, 0.1);
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
  }

  .gnbocd::-webkit-scrollbar-thumb {
    background-color: rgba(133, 138, 148, 0.938);
    background-clip: padding-box;
    min-height: 28px;
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
    transition: background-color 0.3s;
    cursor: pointer;
  }

  .gnbocd::-webkit-scrollbar-thumb:hover {
    background-color: rgba(144, 147, 153, 0.3);
  }
  .lbox::-webkit-scrollbar {
    width: 5px;
    height: 5px;
  }

  .lbox::-webkit-scrollbar-track {
    width: 6px;
    background: #484c56;
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
  }

  .lbox::-webkit-scrollbar-thumb {
    background-color: #484c56;
    background-clip: padding-box;
    min-height: 28px;
    -webkit-border-radius: 2em;
    -moz-border-radius: 2em;
    border-radius: 2em;
    transition: background-color 0.3s;
    cursor: pointer;
  }

  .lbox::-webkit-scrollbar-thumb:hover {
    background-color: #484c56;
  }

  .jgdovx {
    margin: 5px 0;
    display: flex;
    justify-content: space-between;
    width: 100%;
  }
  .xugn {
    display: flex;
    /* justify-content: center; */
    align-items: center;
    margin: 5px 0;
    flex-wrap: wrap;
  }
  .xugname {
    width: 80px;
    color: #fff;
    font-size: 16px;
  }
  .xbanner {
    width: 100%;
    font-size: 16px;
    height: 40px;
    background-color: #fff;
    /* line-height: 40px; */
    padding-left: 10px;
    align-content: center;
  }
  .gobackbox {
    width: 80px;
    height: 45px;
    background: #c6ced8;
    display: flex;
    align-items: center;
  }
  .xbannername {
    cursor: pointer;
    font-size: 16px;
    width: 56px;
    height: 28px;
    background: linear-gradient(180deg, #5a6273 0%, #383b42 100%);
    border-radius: 2px 2px 2px 2px;
    text-align: center;
    line-height: 28px;
    margin: 0 auto;
    color: #fff;
  }
  /* 公共类 */
  /* 封装公共按钮类 */
  .tool {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .tool img.active {
    cursor: pointer;
    display: none;
  }

  .tool:hover img.normal,
  .tool.active img.normal {
    display: none;
  }

  .tool:hover img.active,
  .tool.active img.active {
    display: block;
  }
  .gnboxmain {
    padding: 0 15px;
  }
  .gnboxitem {
    height: 40px;
    background: #24292d;
    border-radius: 4px 4px 4px 4px;
    display: flex;
    align-items: center;
    color: #fff;
    padding: 0 12px;
    margin: 10px 0;
    font-size: 16px;
  }
  .zsbox {
    width: 20%;
    height: 100%;
    background: linear-gradient(180deg, #727786 0%, #484c56 1%);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0px;
    right: 0px;
    z-index: 9999;
  }

  .zsbot {
    height: 90%;
    overflow-y: auto;
  }

  .zsclose {
    position: absolute;
    right: 20px;
    cursor: pointer;
  }

  .jpan {
    background-color: #424548;
    border-radius: 4px;
    /* padding: 10px 28px; */
    cursor: pointer;
    width: 108px;
    height: 38px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 5px 7px;
    text-align: center;
  }
  .jpanitem {
    width: 70%;
    color: #fff;
    text-wrap: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .jpan:hover {
    background-color: #409eff;
    border-radius: 4px;
    max-width: 108px;
  }
  .jpanac {
    background-color: #409eff;
    border-radius: 4px;
    max-width: 108px;
  }
  .overlayCanvastool {
    position: absolute;
    top: 10px;
    right: 100px;
    z-index: 999;
    width: 600px;
    height: 70px;
    background-color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .overlayCanvastooitem {
    width: 50px;
    font-size: 30px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .mentname {
    width: 100%;
    height: 53px !important;
    box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.5);
    border-radius: 0px 0px 0px 0px;
    border-bottom: 1px solid #232429;
    padding: 11px 15px;
    display: flex;
    align-items: center;
    color: #fff;
    justify-content: space-between;
    font-size: 18px;
  }
  .menttitle img {
    width: 13px;
    height: 15px;
    margin: 0px 1px;
  }
  .mentright img {
    width: 29px;
    height: 34px;
    margin-top: 7px;
  }
  .mentbjbox {
    display: flex;
    flex-direction: column;
    padding: 10px 15px;
    box-shadow: 0px 1px 0px 0px rgba(255, 255, 255, 0.5);
    border-radius: 0px 0px 0px 0px;
    border-bottom: 1px solid #232429;
  }
  .mentbjtitle {
    color: #ffffff;
    font-size: 18px;
    margin: 10px 0;
  }
  .mentbjtiem {
    width: 291px;
    height: 46px;
    background: #3d4147;
    border-radius: 4px 4px 4px 4px;
    border: 1px solid #5c616d;
    margin: 10px auto;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .mentsxbox {
    width: 260px;
    min-height: 46px;
    background: #3d4147;
    border-radius: 4px 4px 4px 4px;
    border: 1px solid #5c616d;
    margin: 10px auto;
    display: flex;
    flex-direction: column;
    padding: 15px;
  }
  .mentsxtitle {
    color: #c8c8d2;
    font-size: 16px;
    margin-bottom: 10px;
  }
  .mentbjtiems {
    color: #c8c8d2;
    font-size: 16px;
    align-items: center;
    padding: 0px 10px;
  }
  .mentsxtitembox {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
  }
  .mentsxitems {
    background: linear-gradient(180deg, #ffffff 0%, #c4c4ca 100%);
    color: #000000;
    width: 60px;
    height: 33px;
    border-radius: 4px 4px 4px 4px;
    text-align: center;
    line-height: 33px;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0px 10px;
    margin: 5px 3px;
    cursor: pointer;
  }
  .mentsxitem {
    width: 60px;
    height: 33px;
    background: linear-gradient(180deg, #cacad1 0%, #9898a2 100%);
    border-radius: 4px 4px 4px 4px;
    text-align: center;
    line-height: 33px;
    font-size: 14px;
    color: #666666;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 0px 10px;
    margin: 5px 3px;
    cursor: pointer;
  }
  .mentsxitem:nth-child(3) {
    margin-right: 0px;
  }
  .mentbjtiem .arco-switch {
    background: linear-gradient(160deg, #a7a7a7 0%, #fdfdfd 100%);
    box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
    border-radius: 20px;
  }
  .mentbjtiem .arco-switch-checked {
    background: linear-gradient(180deg, #8cc2ed 0%, #2f7ebd 100%);
    box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
  }
  .mentbjacitem {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .mentbjacitemtool {
    margin: 0px 6px;
  }
  .mentbjacitemtool img {
    width: 35px;
    height: 35px;
  }
  .colorts {
    position: absolute;
    z-index: 999;
    width: 35px;
    opacity: 0;
  }
  .hbcbox {
    width: 80px;
    height: 105px;
    background: #808080;
    border-radius: 10px 10px 10px 10px;
    position: absolute;
    top: 40px;
    right: -25px;
    display: flex;
    align-items: center;
    flex-direction: column;
    padding: 10px 0px;
    overflow: hidden;
  }

  .hbcitem {
    width: 50px;
    height: 0px;
    border-radius: 4px;
    margin: 5px 0;
  }
  .hbcbox :first-child {
    margin-top: 0px;
  }
  .clseo {
    width: 30px !important;
    height: 30px !important;
    cursor: pointer;
  }
  .sbodyd {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
  }

  .loader-container {
    text-align: center;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
    position: fixed;
    top: 0px;
    left: 0px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    z-index: 99;
  }
  .loader {
    border: 8px solid #f3f3f3;
    border-top: 8px solid #3498db;
    border-radius: 50%;
    width: 50px;
    height: 50px;
    animation: spin 1s linear infinite;
    margin: 20px auto;
  }
  @keyframes spin {
    0% {
      transform: rotate(0deg);
    }

    100% {
      transform: rotate(360deg);
    }
  }

  .pd {
    font-family: Arial, sans-serif;
    color: #fff;
    font-size: 16px;
    margin-top: 10px;
  }
  /* 滚动条美化 */
  .beautifulScroll::-webkit-scrollbar {
    width: 5px;
    height: 5px;
    background: rgba(0, 0, 0, 0);
    border-radius: 5px;
  }

  .beautifulScroll::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0);
    border-radius: 5px;
  }

  .beautifulScroll::-webkit-scrollbar-thumb {
    border-radius: 5px;
    background: #666666;
  }
</style>
